package com.example.demo.lucene;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.lucene.search.SortField;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.ParseException;
import java.util.*;


public class LuceneTool {
    private final static Logger log = LoggerFactory.getLogger(LuceneTool.class);
    private String table;
    LuceneManage luceneManage;

    public LuceneTool (String tableName){
        luceneManage=LuceneManage.getInstance();
        this.table=tableName;
    }
    public boolean addList(List<List<Field>> list) {
         return luceneManage.add(list,table);
    }

    /**
     * 添加
     * @param list  对象数组集合
     * @param text  分词数组
     * @param stored  只存储字段数组
     * @return
     */
    private boolean addList(List<Object> list,String[] text,String[] stored) {
        List<List<Field>> arr =new ArrayList<>();
        for (Object obj : list) {
            Class<?> clazz = obj.getClass();
            java.lang.reflect.Field[] declaredFields = clazz.getDeclaredFields();
            List<Field> fields = new ArrayList<>();
            for (java.lang.reflect.Field declaredField : declaredFields) {
                declaredField.setAccessible(true);
                String fieldName = declaredField.getName();
                //判断字段类型为时间特殊处理
                Field field=null;
                try {
                    String name = declaredField.getType().getName();
                    field=type_judgment(field,name,declaredField,obj,fieldName,text,stored);
                } catch (IllegalAccessException e) {
                    log.info("访问权限的异常:"+e.getMessage());
                    return false;
                } catch (ParseException e) {
                    log.info("时间类型解析异常:"+e.getMessage());
                    return false;
                }
                fields.add(field);
            }
            arr.add(fields);
        }

        return luceneManage.add(arr, table);
    }

    private boolean addList(List<Object> list,String ...text) {
        List<List<Field>> arr =new ArrayList<>();
        for (Object obj : list) {
            Class<?> clazz = obj.getClass();
            java.lang.reflect.Field[] declaredFields = clazz.getDeclaredFields();
            List<Field> fields = new ArrayList<>();
            for (java.lang.reflect.Field declaredField : declaredFields) {
                declaredField.setAccessible(true);
                String fieldName = declaredField.getName();
                //判断字段类型为时间特殊处理
                Field field=null;
                try {
                    String name = declaredField.getType().getName();
                    field=type_judgment(field,name,declaredField,obj,fieldName,text,null);
                } catch (IllegalAccessException e) {
                    log.info("访问权限的异常:"+e.getMessage());
                    return false;
                } catch (ParseException e) {
                    log.info("时间类型解析异常:"+e.getMessage());
                    return false;
                }
                fields.add(field);
            }
            arr.add(fields);
        }

        return luceneManage.add(arr, table);
    }

//    public boolean addMap(Map<String,Object> param,String ...text) {
//        List<List<Field>> arr =new ArrayList<>();
//        Field field=null;
//        Set<Map.Entry<String, Object>> entries = param.entrySet();
//        for (Map.Entry<String, Object> entry : entries) {
//            field=type_judgment(field,entry.getKey(),)
//        }
//
//        return luceneManage.add(arr, table);
//    }


    /**
     * 添加对象和需要分词的数据
     * @param obj  对象
     * @Param text 分词数据的key值
     * @return
     */
    public boolean add(Object obj,String[] text){
        if (obj==null)return false;
        if (obj  instanceof Collection){
            log.info("Object传输请用实体对象！");
            return false;
        }
        //增加map对象的限制
        if (obj instanceof Map){
            log.info("Object传输请用实体对象！");
            return false;
        }
        List<List<Field>> arr =new ArrayList<>();
        Class<?> clazz = obj.getClass();
        java.lang.reflect.Field[] declaredFields = clazz.getDeclaredFields();
        List<Field> fields = new ArrayList<>();
        for (java.lang.reflect.Field declaredField : declaredFields) {
            declaredField.setAccessible(true);
            String fieldName = declaredField.getName();
            //判断字段类型为时间特殊处理
            Field field=null;
            try {
            String name = declaredField.getType().getName();
            field=type_judgment(field,name,declaredField,obj,fieldName,text,null);
            } catch (IllegalAccessException e) {
                log.info("访问权限的异常:"+e.getMessage());
                return false;
            } catch (ParseException e) {
                log.info("时间类型解析异常:"+e.getMessage());
                return false;
            }
            fields.add(field);
        }

        arr.add(fields);
        return luceneManage.add(arr, table);
    }

    /**
     * 添加对象和需要分词的数据、只存储的数据
     * @param obj  对象
     * @param text  分词数组
     * @param stored 只存储字段数组
     * @return
     */
    public boolean add(Object obj,String[] text,String[] stored)  {
        if (obj==null)return false;
        if (obj  instanceof Collection){
            List<Object> objects = Arrays.asList(obj);
            return addList(objects,text,stored);

        }
        List<List<Field>> arr =new ArrayList<>();
        Class<?> clazz = obj.getClass();
        java.lang.reflect.Field[] declaredFields = clazz.getDeclaredFields();
        List<Field> fields = new ArrayList<>();
        for (java.lang.reflect.Field declaredField : declaredFields) {
            declaredField.setAccessible(true);
            String fieldName = declaredField.getName();
            Field field= null;
            try {
            String name = declaredField.getType().getName();
            field=type_judgment(field,name,declaredField,obj,fieldName,text,stored);
            } catch (IllegalAccessException e) {
                log.info("访问权限的异常:"+e.getMessage());
                return false;
            } catch (ParseException e) {
                log.info("时间类型解析异常:"+e.getMessage());
                return false;
            }
            fields.add(field);
        }
        arr.add(fields);
        return luceneManage.add(arr, table);
    }




    /**
     * 查询
     * @param page 页数
     * @param size  每页总数
     * @param sortField 排序
     * @param fields 查询条件
     * @return
     */
    public Page select(int page, int size, SortField[] sortField, Field[] fields) {
        if (page<0 || size<0){page=1;size=1;}
        int totalpage=(page-1)*size;
        size=(size>0)?size:Integer.MAX_VALUE;
        return luceneManage.select(totalpage,size,fields, sortField, table);
    }




    /**
     * 删除
     */
    public int delete(Field... fields) {
        for (Field field : fields) {
            int delete = luceneManage.delete(field, table);
            if (delete != 200) return ResultSet.ERROR_SERVER;//"删除到：id[" + field.getValue() + "]时失败!"
        }
        return ResultSet.SUCCESS_OK;
    }

    /**
     * 修改
     */
    public int update(List<Map<String, List<Field>>> arr,String tableName) {
        return luceneManage.update(arr, tableName);
    }




    /**
     * 获取日期转换为时间戳
     * @return
     */
    private String time_stamp(String time) throws ParseException {
        if(StringUtils.isEmpty(time) ) {
            return "0";
        }
        String[] parsePatterns={
                "yyyy-MM-dd",
                "yyyy/MM/dd",
                "yyyy.MM.dd",
                "yyyy-MM",
                "dd/MM/yyyy",
                "yyyy.MM",
                "yyyy",
                "yyyy.MM.dd",
                "HH:mm:ss",
                "yyyy-MM-dd HH:mm:ss",
                "yyyyMMdd HHmmss",
                "yyyyMMddHHmmss",
                "yyyy-MM-dd'T'HH:mm:ss",
                "yyyy-MM-dd'T'HH:mm:ss.SSS",
                "EEEE MMM dd HH:mm:ss Z yyyy",
                "MMM d, yyyy HH:mm:ss a",
                "yyyy年MM月dd日 HH时mm分ss秒"};
        Date date= new Date();
        date = DateUtils.parseDate(time,Locale.US, parsePatterns);
        Long time1 = date.getTime();
        return time1.toString();
    }
    private Field type_judgment(Field field,String name,java.lang.reflect.Field declaredField,Object obj,String fieldName,String[] text,String[] stored) throws IllegalAccessException, ParseException {
        if (fieldName.equals("id")|| fieldName.equals("ID")){
            field=new Field(fieldName,declaredField.get(obj).toString(),Field.Type.Key);
        }
        else if (name.equals("java.sql.Timestamp") || name.equals("java.sql.Date")){

            String date=declaredField.get(obj)==null?"":declaredField.get(obj).toString();
            field=new Field(fieldName,time_stamp(date),Field.Type.Long);
        }
        else if (name.equals("int")){
            field=new Field(fieldName,declaredField.get(obj).toString(),Field.Type.Integer);
        }
        else if (name.equals("long")){
            field=new Field(fieldName,declaredField.get(obj).toString(),Field.Type.Long);
        }
        else if (name.equals("java.lang.Double")){
            field=new Field(fieldName,declaredField.get(obj)==null?"0":declaredField.get(obj).toString(),Field.Type.Double);
        }
        else {
            field=new Field(fieldName,declaredField.get(obj)==null?"":declaredField.get(obj).toString(),Field.Type.String);
//            if (stored!=null){
//                for (String s : stored) {
//                    if (s.equals(fieldName)) {
//                        field = new Field(s, declaredField.get(obj) + "", Field.Type.Stored);
//                    }
//                }
//            }
            if (text!=null){
                for (String s : text) {
                    if (s.equals(fieldName)) {
                        field = new Field(s, declaredField.get(obj)==null?"":declaredField.get(obj).toString(), Field.Type.Text);
                    }
                }
            }

        }
        return field;
    }

    private Field type_judgment(Field field,String name,java.lang.reflect.Field declaredField,Object obj,String fieldName,String[] stored) throws IllegalAccessException, ParseException {
        if (fieldName.equals("id")|| fieldName.equals("ID")){
            field=new Field(fieldName,declaredField.get(obj).toString(),Field.Type.Key);
        }
        else if (name.equals("java.sql.Timestamp") || name.equals("java.sql.Date")){

            String date=declaredField.get(obj)==null?"":declaredField.get(obj).toString();
            field=new Field(fieldName,time_stamp(date),Field.Type.Long);
        }
        else if (name.equals("int")){
            field=new Field(fieldName,declaredField.get(obj).toString(),Field.Type.Integer);
        }
        else if (name.equals("long")){
            field=new Field(fieldName,declaredField.get(obj).toString(),Field.Type.Long);
        }
        else if (name.equals("java.lang.Double")){
            field=new Field(fieldName,declaredField.get(obj)==null?"0":declaredField.get(obj).toString(),Field.Type.Double);
        }
        else {
            field=new Field(fieldName,declaredField.get(obj)==null?"":declaredField.get(obj).toString(),Field.Type.String);
            if (stored!=null){
                for (String s : stored) {
                    if (s.equals(fieldName)) {
                        field = new Field(s, declaredField.get(obj) + "", Field.Type.Stored);
                    }
                }
            }

        }
        return field;
    }

//    public static void main(String[] args) {
//        Info info = new Info();
//        info.setId(1);
//        info.setType(1);
//        info.setTitle(null);
//        info.setBuilding("四川成都");
//        info.setBuilt_area(0D);
//        info.setLogo("");
//        info.setPrice(11.11);
//        Info info2 = new Info();
//        info2.setId(2);
//        info2.setType(1);
//        info2.setTitle(null);
//        info2.setBuilding("四川巴中");
//        info2.setBuilt_area(22.35);
//        info2.setLogo("");
//        info2.setPrice(11.11);
//        List<Info> list = new ArrayList<>();
//        list.add(info);
//        list.add(info2);
//        LuceneTool info1 = new LuceneTool("info");
//        String[] str ={"title"};
//
//        System.out.println(info1.add(list, str));
//
//    }

}